﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using Gurucore.Framework.Core;

namespace Gurucore.Framework.DataAccess.Persistence
{
	public class GenericDTO : IManageableDTO
	{
		private Dictionary<string, object> m_dicColumn;

		internal Dictionary<string, object> Column
		{
			get { return m_dicColumn; }
			set { m_dicColumn = value; }
		}

		private Dictionary<string, DTOColumnState> m_dicColumnState;
		private Dictionary<string, Type> m_dicSchema;

		public GenericDTO() : base()
		{
			m_dicColumn = new Dictionary<string, object>();
			m_dicColumnState = new Dictionary<string, DTOColumnState>();
			m_dicSchema = new Dictionary<string, Type>();
		}

		public object this[string index]
		{
			get
			{
				return m_dicColumn[index];
			}
			set
			{
				this.SetValue(index, value);
				this.SetColumnState(index, DTOColumnState.Changed);
			}
		}

		internal void SetSchema(string p_sColumn, Type p_sDataType)
		{
			m_dicSchema[p_sColumn] = p_sDataType;
		}

		internal void SetValue(string p_sColumn, object p_oValue)
		{
			if (p_oValue != null)
			{
				if (!m_dicColumn.ContainsKey(p_sColumn))
				{
					//create schema
					if (!m_dicSchema.ContainsKey(p_sColumn))
					{
						m_dicSchema.Add(p_sColumn, p_oValue.GetType());
					}
					else
					{
						//check against schema
						if (!m_dicSchema[p_sColumn].Equals(p_oValue.GetType()))
						{
							throw new FrameworkException("Column type mismatch: " + p_sColumn, null);
						}
					}

					m_dicColumn.Add(p_sColumn, p_oValue);
					//m_dicIsNull.Add(p_sColumn, false);
				}
				else
				{
					//check against schema
					if (!m_dicSchema[p_sColumn].Equals(p_oValue.GetType()))
					{
						throw new FrameworkException("Column type mismatch: " + p_sColumn, null);
					}

					m_dicColumn[p_sColumn] = p_oValue;
					//this.SetNotNull(p_sColumn);
				}
			}
			else
			{
				m_dicColumn[p_sColumn] = null;
				//m_dicIsNull[p_sColumn] = true;
				m_dicSchema[p_sColumn] = typeof(int);//default as int
			}
		}

		public DTOColumnState GetColumnState(string p_sColumn)
		{
			return m_dicColumnState[p_sColumn];
		}

		public void SetColumnState(string p_sColumn, DTOColumnState p_eState)
		{
			m_dicColumnState[p_sColumn] = p_eState;
		}
	}
}
